import unittest
import datetime
from random import randint
from a115 import dateutils
from a115 import mathutils
from a115 import tuplify

class TestDateUtils(unittest.TestCase):
	def testParseDate(self):
		self.assertEquals(dateutils.parse_date("16.01.1981"), datetime.date(1981, 1, 16))
		self.assertEquals(dateutils.parse_date("1/2/3456"), datetime.date(3456, 2, 1))
		self.assertEquals(dateutils.parse_date("03 5/2007"), datetime.date(2007, 5, 3))
		self.assertEquals(dateutils.parse_date("1994, 6/13"), datetime.date(1994, 6, 13))
	def testBGDate(self):
		self.assertEquals(dateutils.bg_date(datetime.date(1994, 7, 15)), "15.07.1994")
	def testRandomDate(self):
		self.assertEquals(dateutils.random_date(datetime.date(2008,1,16), datetime.date(2007,1,17)), False)
		self.assertEquals(dateutils.random_date(datetime.date(2008,1,16), datetime.date(2008,1,16)), datetime.date(2008,1,16))
		for i in range(1,1000):
			self.assertEquals(len(dateutils.bg_date(dateutils.random_date())), 10)
		startDate = dateutils.random_date(datetime.date(900,1,1), datetime.date(5000,1,1))
		endDate = startDate+datetime.timedelta(days=365000)
		for i in range(1,1000):
			self.assertTrue(startDate <= dateutils.random_date(startDate, endDate) <= endDate)
	def testDayShortcuts(self):
		self.assertEquals(dateutils.today(), datetime.date.today())
		self.assertEquals(dateutils.tomorrow() - dateutils.yesterday(), datetime.timedelta(2))
	def testWeekdateutils(self):
		self.assertEquals(dateutils.startWeek(datetime.date(2008, 12, 30)), datetime.date(2008, 12, 29))
		self.assertEquals(dateutils.endWeek(datetime.date(2008, 12, 30)), datetime.date(2009, 1, 4))
		for i in range(1,1000):
			rd = dateutils.random_date(datetime.date(900,1,1), datetime.date(5000,1,1))
			self.assertTrue(dateutils.startWeek(rd) <= rd <= dateutils.endWeek(rd))
	
	def testDateRange(self):
		self.assertEquals(list(dateutils.date_range(datetime.date(2008, 12, 30), datetime.date(2008, 12, 30))), [datetime.date(2008, 12, 30)])
		self.assertEquals(len(list(dateutils.date_range(datetime.date(2006, 5, 15), datetime.date(2009, 8, 12)))), 1186)

class TestMathUtils(unittest.TestCase):
	def testSimpleBalance(self):
		for attempt in range(0, 50):
			lst = [randint(0, 1000) for r in range(0, 100)]
			lst_sum = sum(lst)
			up_limit = lst_sum - randint(0, lst_sum)
			out = mathutils.simple_balance(lst, up_limit)
			out_sum = sum(out)
			self.assertEquals(len(lst), len(out))
			self.assertEquals(out_sum, up_limit)
			for i in range(0, len(lst)):
				self.assertTrue(out[i] <= lst[i])
	def testProportionalBalance(self):
		for attempt in range(0, 50):
			lst = [randint(0, 1000) for r in range(0, 100)]
			lst_sum = sum(lst)
			up_limit = lst_sum - randint(0, lst_sum)
			out = mathutils.proportional_balance(lst, up_limit)
			out_sum = sum(out)
			self.assertEquals(len(lst), len(out))
			self.assertEquals(out_sum, up_limit)
			for i in range(0, len(lst)):
				self.assertTrue(out[i] <= lst[i])

class TestA115Utils(unittest.TestCase):
	def testTuplify(self):
		from math import ceil
		lst = [1,2,3,4,5,6,7,8,9]
		out = tuplify(lst)
		self.assertEquals(out, [(1, 2), (3, 4), (5, 6), (7, 8), (9,)])
		for attempt in range(0, 50):
			lst = [randint(0, 100) for r in range(0, randint(0, 1000))]
			maxN = randint(1, 100)
			out = tuplify(lst, n=maxN)
			self.assertEquals(int(ceil(float(len(lst)) / maxN)), len(out))
			lenOut = 0
			for tpl in out:
				self.assertTrue(len(tpl) <= maxN)
				lenOut += len(tpl)
			self.assertEquals(lenOut, len(lst))
